﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.XPath;

namespace Allegro.TaskExecution
{
    /// <summary>
    /// Persistent item
    /// </summary>
    public abstract class PersistentItem : IXmlPersist, IIdentity
    {
        private string _namespace;
        private string _xmlElementName;
        private Guid _oid;
        private string _name;

        /// <summary>
        /// 
        /// </summary>
        protected PersistentItem()
        {
            _oid = Guid.NewGuid();
            _xmlElementName = GetType().Name;
            _namespace = string.Format("clr-namespace:{0}", GetType().Namespace);
        }
        /// <summary>
        /// Object id
        /// </summary>
        public Guid Oid
        {
            get { return _oid; }
        }
        /// <summary>
        /// Name
        /// </summary>
        public virtual string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        /// <summary>
        /// Save to XML
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="persistenceContext"></param>
        public void Save(XmlWriter writer, IXmlPersistenceContext persistenceContext)
        {
            writer.WriteStartElement(XmlElementName, XmlNamespace);
            writer.WriteAttributeString("oid", _oid.ToString());
            writer.WriteAttributeString("name", Name);

            // Other attributes
            SaveAttributes(writer, persistenceContext);
            // Inner XML
            SaveContent(writer, persistenceContext);

            writer.WriteEndElement();
        }

        /// <summary>
        /// Load from XML
        /// </summary>
        /// <param name="navigator"></param>
        /// <param name="persistenceContext"></param>
        public void Load(XPathNavigator navigator, IXmlPersistenceContext persistenceContext)
        {
            XmlNamespaceManager nsMgr = persistenceContext.NamespaceManager;
            // @oid
            XPathNavigator attribNode = navigator.SelectSingleNode("@oid");
            if (attribNode != null)
                _oid = new Guid(attribNode.Value);

            // @name
            attribNode = navigator.SelectSingleNode("@name");
            _name = attribNode.Value;
            // Other attributes
            LoadAttributes(navigator, persistenceContext);
            // Inner XML
            LoadContent(navigator, persistenceContext);
        }

        // Abstracts and virtuals:
        /// <summary>
        /// 
        /// </summary>
        protected virtual string XmlElementName
        {
            get
            {
                return _xmlElementName;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        protected virtual string XmlNamespace
        {
            get
            {
                return _namespace;
            }
        }
        /// <summary>
        /// Override in order to load class specific attributes
        /// </summary>
        /// <param name="itemNode"></param>
        /// <param name="persistenceContext"></param>
        protected virtual void LoadAttributes(XPathNavigator itemNode, IXmlPersistenceContext persistenceContext)
        {

        }
        /// <summary>
        /// Override in order to save class specific attributes
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="persistenceContext"></param>
        protected virtual void SaveAttributes(XmlWriter writer, IXmlPersistenceContext persistenceContext)
        {

        }
        /// <summary>
        /// Override in order to load class specific content
        /// </summary>
        /// <param name="itemNode"></param>
        /// <param name="persistenceContext"></param>
        protected virtual void LoadContent(XPathNavigator itemNode, IXmlPersistenceContext persistenceContext)
        {
            
        }
        /// <summary>
        /// Override in order to save class specific content
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="persistenceContext"></param>
        protected virtual void SaveContent(XmlWriter writer, IXmlPersistenceContext persistenceContext)
        {
            
        }
        
    }
}
